package org.apache.rocketmq.client.java.rpc;

import io.grpc.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.UUID;

/**
 * @课程描述:从零带你写框架系列中的课程，整个系列包含netty，xxl-job，rocketmq，nacos，sofajraft，spring，springboot，disruptor，编译器，虚拟机等等。
 * @author：陈清风扬，个人微信号：chenqingfengyangjj。
 * @date:2025/6/10
 * @方法描述：日志拦截器
 */
public class LoggingInterceptor implements ClientInterceptor {
    private static final Logger LOGGER = LoggerFactory.getLogger(LoggingInterceptor.class);

    private static final LoggingInterceptor INSTANCE = new LoggingInterceptor();

    public static LoggingInterceptor getInstance() {
        return INSTANCE;
    }

    @Override
    public <T, E> ClientCall<T, E> interceptCall(MethodDescriptor<T, E> method,
                                                 CallOptions callOptions, Channel next) {

        final String rpcId = UUID.randomUUID().toString();
        final String authority = next.authority();
        final String serviceName = method.getServiceName();
        final String methodName = method.getBareMethodName();

        return new ForwardingClientCall.SimpleForwardingClientCall<T, E>(next.newCall(method, callOptions)) {
            @Override
            public void start(Listener<E> responseListener, final Metadata headers) {
                LOGGER.trace("gRPC request header, rpcId={}, serviceName={}, methodName={}, authority={}, headers={}",
                        rpcId, serviceName, methodName, authority, headers);
                Listener<E> observabilityListener =
                        new ForwardingClientCallListener.SimpleForwardingClientCallListener<E>(responseListener) {
                            @Override
                            public void onMessage(E response) {
                                LOGGER.trace("gRPC response, rpcId={}, serviceName={}, methodName={}, content:\n{}",
                                        rpcId, serviceName, methodName, response);
                                super.onMessage(response);
                            }

                            @Override
                            public void onHeaders(Metadata headers) {
                                LOGGER.trace("gRPC response header, rpcId={}, serviceName={}, methodName={}, "
                                        + "authority={}, headers={}", rpcId, serviceName, methodName, authority, headers);
                                super.onHeaders(headers);
                            }
                        };
                super.start(observabilityListener, headers);
            }

            @Override
            public void sendMessage(T request) {
                LOGGER.trace("gRPC request, rpcId={}, serviceName={}, methodName={}, content:\n{}", rpcId,
                        serviceName, methodName, request);
                super.sendMessage(request);
            }
        };
    }
}
